from tkinter import Tk, END, Frame, Label, Button, Text, messagebox, filedialog, Entry

from pdfplumber import open as open2
from PyPDF2 import PdfWriter, PdfReader
from openpyxl.workbook import Workbook


def merge_pdf():
    pdf_files = []
    tip.pack(side='top')

    def new():
        [pdf_files.remove(i) for i in pdf_files if not i]
        (Buttons1[0].config(state='normal'), Buttons1[1].config(state='normal')) if len(pdf_files) > 0 else \
            (Buttons1[0].config(state='disabled'), Buttons1[1].config(state='disabled'))
        tip.delete(1.0, END)
        [tip.insert('end', str(i) + '\n') for i in pdf_files]

    def select_file():
        pdf_files.append(filedialog.askopenfilename(title='请选择一个PDF文件！', filetypes=[('PDF Files', '*.pdf')]))
        new()

    def select_files():
        [pdf_files.append(_path) for _path in
         filedialog.askopenfilenames(title='请选择多个PDF文件！', filetypes=[('PDF Files', '*.pdf')])]
        new()

    def clear():
        pdf_files.clear()
        new()

    def merge():
        save_folder = filedialog.asksaveasfilename(title='请选择PDF保存路径和文件名！',
                                                   filetypes=[('PDF Files', '*.pdf')])
        save_folder = save_folder if save_folder.endswith('.pdf') else save_folder + '.pdf'
        pdf_writer = PdfWriter()
        for inFile in pdf_files:
            pdf_reader = PdfReader(open(inFile, 'rb'))
            for index in range(len(pdf_reader.pages)):
                pdf_writer.add_page(pdf_reader.pages[index])
            pdf_writer.write(open(save_folder, 'wb'))
        tip.insert('end', f'\n合并文件保存为：{save_folder}\n')
        messagebox.showinfo(title='合并成功！', message=f'保存为{save_folder}')

    [button.config(text='') for button in Buttons0 + Buttons1]
    Buttons0[0].config(text='逐个添加PDF文件', command=select_file)
    Buttons0[1].config(text='批量添加PDF文件', command=select_files)
    Buttons1[0].config(text='清空选择', command=clear)
    Buttons1[1].config(text='合并文件', command=merge)
    [button.pack(side='left') for button in Buttons0 + Buttons1 if button.cget('text')]
    [button.pack_forget() for button in Buttons0 + Buttons1 if not button.cget('text')]
    Label1_1.pack_forget()
    Entry1_1.pack_forget()
    new()


def pdf_info():
    tip.pack(side='top')

    def info():
        path = filedialog.askopenfilename(title='请选择一个PDF文件！', filetypes=[('PDF Files', '*.pdf')])
        with open(path, 'rb') as f:
            pdf = PdfReader(f)
            information = pdf.metadata
            txt = f'{path}\n<PDF文件信息>\n作者 : {information.author}\n发明者 : {information.creator}\n' \
                  f'产生方式 : {information.producer}\n主题 : {information.subject}\n' \
                  f'标题 : {information.title}\n页数 : {len(pdf.pages)} '
            tip.delete(1.0, END)
            tip.insert('end', txt)

    [button.config(text='') for button in Buttons0 + Buttons1]
    Buttons0[0].config(text='选择PDF文件', command=info)
    [button.pack(side='left') for button in Buttons0 + Buttons1 if button.cget('text')]
    [button.pack_forget() for button in Buttons0 + Buttons1 if not button.cget('text')]
    Label1_1.pack_forget()
    Entry1_1.pack_forget()


def pdf_table():
    path = []
    tip.pack(side='top')

    def new():
        [path.remove(i) for i in path if not i]
        (Buttons1[0].config(state='normal'), Buttons1[1].config(state='normal')) if len(path) > 0 else \
            (Buttons1[0].config(state='disabled'), Buttons1[1].config(state='disabled'))
        tip.delete(1.0, END)
        [tip.insert('end', str(i) + '\n') for i in path]

    def info():
        path.clear()
        path.append(filedialog.askopenfilename(title='请选择一个PDF文件！', filetypes=[('PDF Files', '*.pdf')]))
        new()

    def table():
        new()
        save_folder = filedialog.asksaveasfilename(title='请选择表格保存路径和文件名！',
                                                   filetypes=[('Excel Files', '*.xlsx')])
        save_folder = save_folder if save_folder.endswith('.xlsx') else save_folder + '.xlsx'
        page = int(Entry1_1.get())
        with open2(path[0]) as pdf:
            page0 = pdf.pages[page]
            table0 = page0.extract_table()
            tip.insert('end', f'\n{table0}')
            workbook = Workbook()
            sheet = workbook.active
            for row in table0:
                sheet.append(row)
            workbook.save(filename=save_folder)
            tip.insert('end', f'\n文件保存为：{save_folder}\n')
            messagebox.showinfo(title='导出表格成功！', message=f'保存为{save_folder}')

    [button.config(text='') for button in Buttons0 + Buttons1]
    Buttons0[0].config(text='选择PDF文件', command=info)
    Label1_1.config(text='表格所在页数')
    Label1_1.pack(side='left')
    Entry1_1.pack(side='left')
    Buttons1[1].config(text='导出表格', command=table)
    [button.pack(side='left') for button in Buttons0 + Buttons1 if button.cget('text')]
    [button.pack_forget() for button in Buttons0 + Buttons1 if not button.cget('text')]
    new()


def pdf_word():
    path = []
    tip.pack(side='top')

    def new():
        [path.remove(i) for i in path if not i]
        (Buttons1[0].config(state='normal'), Buttons1[1].config(state='normal')) if len(path) > 0 else \
            (Buttons1[0].config(state='disabled'), Buttons1[1].config(state='disabled'))
        tip.delete(1.0, END)
        [tip.insert('end', str(i) + '\n') for i in path]

    def info():
        path.clear()
        path.append(filedialog.askopenfilename(title='请选择一个PDF文件！', filetypes=[('PDF Files', '*.pdf')]))
        new()

    def word():
        new()
        save_folder = filedialog.asksaveasfilename(title='请选择文字保存路径和文件名！',
                                                   filetypes=[('Txt Files', '*.txt')])
        save_folder = save_folder if save_folder.endswith('.txt') else save_folder + '.txt'
        page = int(Entry1_1.get())
        with open(path[0], 'rb') as pdf:
            pdf = PdfReader(pdf)
            page0 = pdf.pages[page]
            text0 = page0.extract_text()
            text0.encode('utf-8').decode('utf-8')
            with open(save_folder, 'wt') as f:
                f.write(text0)
            tip.insert('end', f'\n{text0}')
            tip.insert('end', f'\n文件保存为：{save_folder}\n')
            messagebox.showinfo(title='导出文字成功！', message=f'保存为{save_folder}')

    [button.config(text='') for button in Buttons0 + Buttons1]
    Buttons0[0].config(text='选择PDF文件', command=info)
    Label1_1.config(text='文字所在页数')
    Label1_1.pack(side='left')
    Entry1_1.pack(side='left')
    Buttons1[1].config(text='导出文字', command=word)
    [button.pack(side='left') for button in Buttons0 + Buttons1 if button.cget('text')]
    [button.pack_forget() for button in Buttons0 + Buttons1 if not button.cget('text')]
    new()


root = Tk()
root.title('PDF工具箱 by：wld')
# _w, _h = 500, 700
# root.geometry(f'{_w}x{_h}+{int((root.winfo_screenwidth() - _w) / 2)}+{int((root.winfo_screenheight() - _h) / 2)}')

Label(root, text='-' * 20 + '选择功能' + '-' * 20, font=("宋体", 12)).pack(side='top')
frame_0 = Frame(root)
frame_0.pack(side='top')
Button(frame_0, text='合并PDF', font=("宋体", 12), fg="blue", command=merge_pdf).pack(side='top')
Button(frame_0, text='提取表格', font=("宋体", 12), fg="blue", command=pdf_table).pack(side='top')
Button(frame_0, text='提取文字', font=("宋体", 12), fg="blue", command=pdf_word).pack(side='top')
Button(frame_0, text='PDF信息', font=("宋体", 12), fg="blue", command=pdf_info).pack(side='top')

Label(root, text='-' * 20 + '功能操作' + '-' * 20, font=("宋体", 12)).pack(side='top')
frame_1 = Frame(root)
frame_1.pack(side='top')
frame_1_0 = Frame(frame_1)
frame_1_0.pack(side='top')
Buttons0 = [Button(frame_1_0, font=("宋体", 12), fg="blue") for _ in range(5)]
frame_1_1 = Frame(frame_1)
frame_1_1.pack(side='top')
Label1_1 = Label(frame_1_1, font=("宋体", 12))
Entry1_1 = Entry(frame_1_1, font=("宋体", 12), width=5)
Entry1_1.insert('end', '0')
Buttons1 = [Button(frame_1_1, font=("宋体", 12), fg="blue") for _ in range(5)]

Label(root, text='-' * 20 + '提示信息' + '-' * 20, font=("宋体", 12)).pack(side='top')
frame_2 = Frame(root)
frame_2.pack(side='top')
tip = Text(frame_2, font=("宋体", 12), width=40, height=10)

root.mainloop()
